package com.shangguosha.game;

import com.shangguosha.core.event.EventListener;
import com.shangguosha.core.event.GameStateEvent;
import com.shangguosha.model.Character;
import com.shangguosha.model.Card;
import com.shangguosha.model.enums.GamePhase;
import com.shangguosha.model.enums.EventType;

import java.util.List;

/**
 * 游戏管理器 - 控制游戏流程
 */
public class GameManager {
    private GameContext gameContext;
    private boolean autoNextPhase;
    
    public GameManager() {
        this.gameContext = GameContext.getInstance();
        this.autoNextPhase = true;
        initializeEventListeners();
    }
    
    /**
     * 初始化事件监听器
     */
    private void initializeEventListeners() {
        // 监听游戏开始事件
        gameContext.getEventBus().subscribe(EventType.GAME_STARTED.getEventName(), (EventListener) event -> {
            System.out.println("游戏开始！");
            startFirstTurn();
        });
        
        // 监听阶段变化事件
        gameContext.getEventBus().subscribe(EventType.PHASE_CHANGED.getEventName(), (EventListener) event -> {
            GameStateEvent stateEvent = (GameStateEvent) event;
            Object[] data = (Object[]) stateEvent.getData();
            GamePhase oldPhase = (GamePhase) data[0];
            GamePhase newPhase = (GamePhase) data[1];
            System.out.printf("阶段变化: %s -> %s%n", oldPhase, newPhase);
            
            handlePhaseChange(newPhase);
        });
        
        // 监听玩家变化事件
        gameContext.getEventBus().subscribe(EventType.PLAYER_CHANGED.getEventName(), (EventListener) event -> {
            GameStateEvent stateEvent = (GameStateEvent) event;
            Character newPlayer = (Character) stateEvent.getData();
            System.out.printf("轮到玩家: %s%n", newPlayer.getName());
        });
        
        // 监听角色死亡事件
        gameContext.getEventBus().subscribe(EventType.CHARACTER_DIED.getEventName(), (EventListener) event -> {
            Character deadCharacter = (Character) event.getSource();
            System.out.printf("角色死亡: %s%n", deadCharacter.getName());
            checkGameEnd();
        });
        
        // 监听游戏结束事件
        gameContext.getEventBus().subscribe(EventType.GAME_ENDED.getEventName(), (EventListener) event -> {
            GameStateEvent stateEvent = (GameStateEvent) event;
            Character winner = (Character) stateEvent.getData();
            if (winner != null) {
                System.out.printf("游戏结束！获胜者: %s%n", winner.getName());
            } else {
                System.out.println("游戏结束！平局");
            }
        });
    }
    
    /**
     * 开始游戏
     */
    public void startGame(List<Character> players) {
        gameContext.initializeGame(players);
        
        // 初始化玩家
        for (Character player : players) {
            player.onCreate();
            player.onActivate();
            
            // 初始摸牌
            for (int i = 0; i < 4; i++) {
                Card card = gameContext.drawCard();
                if (card != null) {
                    player.drawCard(card);
                }
            }
        }
        
        gameContext.startGame();
    }
    
    /**
     * 开始第一回合
     */
    private void startFirstTurn() {
        if (gameContext.getCurrentPlayer() != null) {
            startPlayerTurn(gameContext.getCurrentPlayer());
        }
    }
    
    /**
     * 开始玩家回合
     */
    public void startPlayerTurn(Character player) {
        gameContext.setCurrentPlayer(player);
        gameContext.setCurrentPhase(GamePhase.PREPARE);
        
        System.out.printf("%n=== %s 的回合开始 ===%n", player.getName());
        
        if (autoNextPhase) {
            processPhase(GamePhase.PREPARE);
        }
    }
    
    /**
     * 处理阶段变化
     */
    private void handlePhaseChange(GamePhase newPhase) {
        if (autoNextPhase) {
            processPhase(newPhase);
        }
    }
    
    /**
     * 处理当前阶段
     */
    public void processPhase(GamePhase phase) {
        Character currentPlayer = gameContext.getCurrentPlayer();
        if (currentPlayer == null || !currentPlayer.isAlive()) {
            gameContext.nextPlayer();
            return;
        }
        
        System.out.printf("进入%s%n", phase.getDescription());
        
        switch (phase) {
            case PREPARE:
                processPreparePhase(currentPlayer);
                break;
            case JUDGE:
                processJudgePhase(currentPlayer);
                break;
            case DRAW:
                processDrawPhase(currentPlayer);
                break;
            case PLAY:
                processPlayPhase(currentPlayer);
                break;
            case DISCARD:
                processDiscardPhase(currentPlayer);
                break;
            case END:
                processEndPhase(currentPlayer);
                break;
        }
    }
    
    /**
     * 处理准备阶段
     */
    private void processPreparePhase(Character player) {
        // 重置技能使用次数
        player.getSkills().forEach(skill -> skill.resetUsage());
        
        // 自动进入下一阶段
        if (autoNextPhase) {
            gameContext.nextPhase();
        }
    }
    
    /**
     * 处理判定阶段
     */
    private void processJudgePhase(Character player) {
        // TODO: 处理延时锦囊的判定
        
        // 自动进入下一阶段
        if (autoNextPhase) {
            gameContext.nextPhase();
        }
    }
    
    /**
     * 处理摸牌阶段
     */
    private void processDrawPhase(Character player) {
        // 摸两张牌
        for (int i = 0; i < 2; i++) {
            Card card = gameContext.drawCard();
            if (card != null) {
                player.drawCard(card);
                System.out.printf("%s 摸了一张牌%n", player.getName());
            }
        }
        
        // 自动进入下一阶段
        if (autoNextPhase) {
            gameContext.nextPhase();
        }
    }
    
    /**
     * 处理出牌阶段
     */
    private void processPlayPhase(Character player) {
        System.out.printf("%s 进入出牌阶段，手牌数：%d%n", player.getName(), player.getHandCardCount());
        
        // 在控制台演示中，这里会等待用户输入
        // 现在自动跳过
        if (autoNextPhase) {
            gameContext.nextPhase();
        }
    }
    
    /**
     * 处理弃牌阶段
     */
    private void processDiscardPhase(Character player) {
        int handCardCount = player.getHandCardCount();
        int maxHandCards = player.getCurrentHp();
        
        if (handCardCount > maxHandCards) {
            int discardCount = handCardCount - maxHandCards;
            System.out.printf("%s 需要弃置 %d 张牌%n", player.getName(), discardCount);
            
            // 在实际游戏中，这里需要玩家选择弃牌
            // 现在自动弃置前几张牌
            for (int i = 0; i < discardCount && !player.getHandCards().isEmpty(); i++) {
                Card card = player.getHandCards().get(0);
                player.discardCard(card);
                gameContext.discardCard(card);
                System.out.printf("%s 弃置了一张牌%n", player.getName());
            }
        }
        
        // 自动进入下一阶段
        if (autoNextPhase) {
            gameContext.nextPhase();
        }
    }
    
    /**
     * 处理结束阶段
     */
    private void processEndPhase(Character player) {
        System.out.printf("%s 的回合结束%n", player.getName());
        
        // 自动进入下一阶段（下一个玩家的回合）
        if (autoNextPhase) {
            gameContext.nextPhase();
        }
    }
    
    /**
     * 检查游戏是否结束
     */
    private void checkGameEnd() {
        int aliveCount = gameContext.getAlivePlayerCount();
        
        if (aliveCount <= 1) {
            Character winner = null;
            if (aliveCount == 1) {
                winner = gameContext.getAlivePlayers().get(0);
            }
            gameContext.endGame(winner);
        }
    }
    
    /**
     * 手动进入下一阶段
     */
    public void nextPhase() {
        if (!gameContext.isGameEnded()) {
            gameContext.nextPhase();
        }
    }
    
    /**
     * 手动切换到下一个玩家
     */
    public void nextPlayer() {
        if (!gameContext.isGameEnded()) {
            gameContext.nextPlayer();
            startPlayerTurn(gameContext.getCurrentPlayer());
        }
    }
    
    /**
     * 获取游戏状态信息
     */
    public String getGameStatus() {
        if (gameContext.isGameEnded()) {
            Character winner = gameContext.getWinner();
            return winner != null ? 
                String.format("游戏已结束，获胜者：%s", winner.getName()) : 
                "游戏已结束，平局";
        }
        
        if (!gameContext.isGameStarted()) {
            return "游戏未开始";
        }
        
        Character currentPlayer = gameContext.getCurrentPlayer();
        GamePhase currentPhase = gameContext.getCurrentPhase();
        
        return String.format("当前玩家：%s，当前阶段：%s，存活玩家数：%d", 
                currentPlayer != null ? currentPlayer.getName() : "无",
                currentPhase.getDescription(),
                gameContext.getAlivePlayerCount());
    }
    
    // Getters and Setters
    public GameContext getGameContext() {
        return gameContext;
    }
    
    public boolean isAutoNextPhase() {
        return autoNextPhase;
    }
    
    public void setAutoNextPhase(boolean autoNextPhase) {
        this.autoNextPhase = autoNextPhase;
    }
}